package com.bilibili.juc.cf.one;

import java.util.Random;
import java.util.concurrent.*;

/*
如果你执行第一个任务的时候，传入了一个自定义线程池：

    调用thenRun方法执行第二个任务时，则第二个任务和第一个任务是共用同一个线程池。
    调用thenRunAsync执行第二个任务时，则第一个任务使用的是你自己传入的线程池，第二个任务使用的是ForkJoin线程池

TIPS: 后面介绍的thenAccept和thenAcceptAsync，thenApply和thenApplyAsync等，它们之间的区别也是这个哈。
2.thenAccept/thenAcceptAsync

CompletableFuture的thenAccept方法表示，第一个任务执行完成后，执行第二个回调方法任务，会将该任务的执行结果，作为入参，传递到回调方法中，但是回调方法是没有返回值的。
* */
public class FutureThenRunTwoTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"自定义线程-"+new Random().nextInt(1000));
            }
        });
        ExecutorService executor2 = Executors.newCachedThreadPool(new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"My**自定义线程-"+new Random().nextInt(1000));
            }
        });

        CompletableFuture<String> orgFuture = CompletableFuture.supplyAsync(
                ()->{
                    System.out.println(Thread.currentThread().getName() + " 先执行第一个CompletableFuture方法任务");
                    return "捡田螺的小男孩";
                },
                executor
        );

/*        CompletableFuture thenRunFuture = orgFuture.thenRun(() -> {
            System.out.println(Thread.currentThread().getName() + " 接着执行第二个任务");
        });*/

        CompletableFuture thenRunFuture2 = orgFuture.thenRunAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " 接着执行第二个任务2");
        },executor2);

//        System.out.println(thenRunFuture.get());
        System.out.println(thenRunFuture2.get());
        executor.shutdown();
        executor2.shutdown();
    }
}
/*
自定义线程-397 先执行第一个CompletableFuture方法任务
My**自定义线程-222 接着执行第二个任务2
null
 */